package com.xbongbong.paas.toolbox.util;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.pro.constant.I18nStringConstant;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * User: 章华隽
 * E-mail: GavinChangCN@163.com
 * Desc: 日历转换工具类：农历和公历日期互换(农历日期范围19000101~20491229)
 * Date: 2017-07-01
 * Time: 16:05
 */
public class CalendarUtil {
    //  private static final Logger logger = LoggerFactory.getLogger(CalendarUtil.class);
    // 计算农历日期参照1900年到2049年
    private static final int[] LUNAR_INFO = {
            0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
            0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
            0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
            0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
            0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
            0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
            0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
            0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
            0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
            0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
            0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
            0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
            0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
            0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
            0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0
    };

    // 允许输入的最小年份
    private static final int MIN_YEAR = 1900;
    // 允许输入的最大年份
    private static final int MAX_YEAR = 2049;
    // 公历日期计算起点
    private static final String START_DATE = "19000130";


    /**
     * 计算农历 {@code year}年闰哪个月 1-12 , 没闰传回 0
     *
     * @param year 农历年
     *
     * @return (int)月份
     * @author liu 2015-1-5
     */
    private static int getLeapMonth(int year) {
        return LUNAR_INFO[year - 1900] & 0xf;
    }

    /**
     * 计算农历{@code year}年闰月多少天
     *
     * @param year 农历年
     *
     * @return (int)天数
     * @author liu 2015-1-5
     */
    private static int getLeapMonthDays(int year) {
        if (getLeapMonth(year) != 0) {
            if ((LUNAR_INFO[year - 1900] & 0xf0000) == 0) {
                return 29;
            } else {
                return 30;
            }
        } else {
            return 0;
        }
    }

    /**
     * 计算农历{@code lunarYeay}年{@code month}月的天数
     *
     * @param lunarYeay 农历年
     * @param month     农历月
     *
     * @return (int)该月天数
     * @throws Exception 月份错误异常
     * @author liu 2015-1-5
     */
    private static int getMonthDays(int lunarYeay, int month) throws Exception {
        if ((month > 31) || (month < 0)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.MONTH_ERROR)));
        }
        // 0X0FFFF[0000 {1111 1111 1111} 1111]中间12位代表12个月，1为大月，0为小月
        int bit = 1 << (16 - month);
        if (((LUNAR_INFO[lunarYeay - 1900] & 0x0FFFF) & bit) == 0) {
            return 29;
        } else {
            return 30;
        }
    }

    /**
     * 计算农历年该月有几天
     *
     * @param lunarYear 农历年
     * @param lunarMonth 农历月
     * @return 该月有几天，29或30 错误数据返回0
     * @throws Exception 农历转换异常
     *
     * @author 章华隽
     * 创建时间： 2017/7/19 下午3:40
     * 修改时间：
     * @version
     * @since 3.9
     */
    public static int getLunarMonthDays(int lunarYear, int lunarMonth) throws Exception {
        int learMonth = CalendarUtil.getLeapMonth(lunarYear); // 农历年的闰月是几月
        if (learMonth == lunarMonth) { // 该月是闰月
            return CalendarUtil.getLeapMonthDays(lunarYear);
        } else { // 该月非闰月
            return CalendarUtil.getMonthDays(lunarYear, lunarMonth);
        }
    }

    /**
     * 计算农历{@code year}年的总天数
     *
     * @param year 农历年
     *
     * @return (int)总天数
     * @author liu 2015-1-5
     */
    private static int getYearDays(int year) {
        int sum = 29 * 12;
        for (int i = 0x8000; i >= 0x8; i >>= 1) {
            if ((LUNAR_INFO[year - 1900] & 0xfff0 & i) != 0) {
                sum++;
            }
        }
        return sum + getLeapMonthDays(year);
    }

    /**
     * 计算两个公历日期相差的天数。
     *
     * @param startDate 开始时间
     * @param endDate   截至时间
     *
     * @return (int)天数
     * @author liu 2017-3-2
     */
    private static int daysBetween(Date startDate, Date endDate) {
        int days = 0;
        //将转换的两个时间对象转换成Calendar对象
        Calendar can1 = Calendar.getInstance();
        can1.setTime(startDate);
        Calendar can2 = Calendar.getInstance();
        can2.setTime(endDate);
        //拿出两个年份
        int year1 = can1.get(Calendar.YEAR);
        int year2 = can2.get(Calendar.YEAR);
        //天数

        Calendar can;
        //如果can1 < can2
        //减去小的时间在这一年已经过了的天数
        //加上大的时间已过的天数
        if (can1.before(can2)) {
            days -= can1.get(Calendar.DAY_OF_YEAR);
            days += can2.get(Calendar.DAY_OF_YEAR);
            can = can1;
        } else {
            days -= can2.get(Calendar.DAY_OF_YEAR);
            days += can1.get(Calendar.DAY_OF_YEAR);
            can = can2;
        }
        for (int i = 0; i < Math.abs(year2 - year1); i++) {
            //获取小的时间当前年的总天数
            days += can.getActualMaximum(Calendar.DAY_OF_YEAR);
            //再计算下一年。
            can.add(Calendar.YEAR, 1);
        }
        return days;
    }

    /**
     * 检查农历日期是否合法
     *
     * @param lunarYear     农历年
     * @param lunarMonth    农历月
     * @param lunarDay      农历日
     * @param leapMonthFlag 闰月标志
     *
     * @throws Exception 非法日期异常
     */
    private static void checkLunarDate(int lunarYear, int lunarMonth, int lunarDay, boolean leapMonthFlag) throws Exception {
        if ((lunarYear < MIN_YEAR) || (lunarYear > MAX_YEAR)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_YEAR)));
        }
        if ((lunarMonth < 1) || (lunarMonth > 12)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_MONTH)));
        }
        if ((lunarDay < 1) || (lunarDay > 30)) { // 中国的月最多30天
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DAY)));
        }

        int leap = getLeapMonth(lunarYear);// 计算该年应该闰哪个月
        if (leapMonthFlag && (lunarMonth != leap)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_MOON)));
        }
    }

    /**
     * 检查农历日期是否合法
     *
     * @param lunarYear  农历年
     * @param lunarMonth 农历月
     * @param lunarDay   农历日
     *
     * @throws Exception 非法日期异常
     */
    private static void checkLunarDate(int lunarYear, int lunarMonth, int lunarDay) throws Exception {
        if ((lunarYear < MIN_YEAR) || (lunarYear > MAX_YEAR)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_YEAR)));
        }
        if ((lunarMonth < 1) || (lunarMonth > 12)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_MONTH)));
        }
        if ((lunarDay < 1) || (lunarDay > 30)) { // 中国的月最多30天
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DAY)));
        }
    }

    /**
     * 农历转换为公历
     *
     * @param lunarDate     农历日期,格式YYYYMMDD
     * @param leapMonthFlag 是否为闰月
     *
     * @return 公历日期, 格式：YYYYMMDD
     * @throws Exception 非法日期异常
     * @author liu 2015-1-5
     */
    public static String lunarToSolar(String lunarDate, boolean leapMonthFlag) throws Exception {
        int lunarYear = Integer.parseInt(lunarDate.substring(0, 4));
        int lunarMonth = Integer.parseInt(lunarDate.substring(4, 6));
        int lunarDay = Integer.parseInt(lunarDate.substring(6, 8));

        checkLunarDate(lunarYear, lunarMonth, lunarDay, leapMonthFlag);

        int offset = 0;

        for (int i = MIN_YEAR; i < lunarYear; i++) {
            int yearDaysCount = getYearDays(i); // 求农历某年天数
            offset += yearDaysCount;
        }
        //计算该年闰几月
        int leapMonth = getLeapMonth(lunarYear);

        if (leapMonthFlag & leapMonth != lunarMonth) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.MONTH_SIGN_ERROR)));
        }

        //当年没有闰月或月份早于闰月或和闰月同名的月份
        if (leapMonth == 0 || (lunarMonth < leapMonth) || (lunarMonth == leapMonth && !leapMonthFlag)) {
            offset = checkNotLeapMonth(offset, lunarYear, lunarMonth, lunarDay);
        } else {//当年有闰月，且月份晚于或等于闰月
            offset = checkLeapMonth(offset, leapMonth, lunarYear, lunarMonth, lunarDay);
        }

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        Date myDate;
        myDate = formatter.parse(START_DATE);
        Calendar c = Calendar.getInstance();
        c.setTime(myDate);
        c.add(Calendar.DATE, offset);
        myDate = c.getTime();

        return formatter.format(myDate);
    }

    /**
     * 将农历转为为公历日志
     *
     * @param lunarCalendar 农历日期,格式YYYY-MM-DD
     *
     * @return 公历日期 秒为单位的10位整数 Timestamp
     * @throws Exception 非法日期异常
     * @author 章华隽
     * 创建时间：2017-07-11 10:22
     * 修改时间：2017-07-12 15:42 by 章华隽
     * @version
     * @since 3.9
     */
    public static Integer lunar2Timestamp(String lunarCalendar) throws Exception {
        if (!lunarCalendar.contains("-")) {
            return 0;
        }
        String[] lunars = lunarCalendar.split("-");
        if (lunars.length < 3) {
            return 0;
        }
        Integer lunarYear = Integer.parseInt(lunars[0]);
        Integer lunarMonth = Integer.parseInt(lunars[1]);
        Integer lunarDay = Integer.parseInt(lunars[2]);

        checkLunarDate(lunarYear, lunarMonth, lunarDay);

        int offset = 0;

        for (int i = MIN_YEAR; i < lunarYear; i++) {
            int yearDaysCount = getYearDays(i); // 求农历某年天数
            offset += yearDaysCount;
        }
        //计算该年闰几月
        int leapMonth = getLeapMonth(lunarYear);

        //当年没有闰月或月份早于闰月或和闰月同名的月份
        if (leapMonth == 0 || lunarMonth < leapMonth) {
            offset = checkNotLeapMonth(offset, lunarYear, lunarMonth, lunarDay);
        } else {//当年有闰月，且月份晚于或等于闰月
            offset = checkLeapMonth(offset, leapMonth, lunarYear, lunarMonth, lunarDay);
        }

        Date tempDate = new SimpleDateFormat("yyyyMMdd").parse(START_DATE);
        Calendar c = Calendar.getInstance();
        c.setTime(tempDate);
        c.add(Calendar.DATE, offset);
        tempDate = c.getTime();

        return DateUtil.getInt(tempDate);
    }

    /**
     * 校验非闰月的日期是否合规
     *
     * @param offset     农历1900年1月1日距当前年1月1日的天数
     * @param lunarYear  当前年
     * @param lunarMonth 当前月
     * @param lunarDay   当前日
     *
     * @return 返回农历1900年1月1日距当前日的天数
     * @throws Exception 非法日期异常
     * @author 章华隽
     * 创建时间： 2017/7/13 上午10:26
     * 修改时间：
     * @version
     * @since 3.9
     */
    private static int checkNotLeapMonth(int offset, Integer lunarYear, Integer lunarMonth, Integer lunarDay) throws Exception {
        for (int i = 1; i < lunarMonth; i++) {
            int tempMonthDaysCount = getMonthDays(lunarYear, i);
            offset += tempMonthDaysCount;
        }

        // 检查日期是否大于最大天
        if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DATE)));
        }
        offset += lunarDay; // 加上当月的天数
        return offset;
    }

    /**
     * 校验闰月的日期是否合规
     *
     * @param offset     农历1900年1月1日距当前年1月1日的天数
     * @param leapMonth  当前年闰几月
     * @param lunarYear  当前年
     * @param lunarMonth 当前月
     * @param lunarDay   当前日
     *
     * @return 返回农历1900年1月1日距当前日的天数
     * @throws Exception 非法日期异常
     * @author 章华隽
     * 创建时间： 2017/7/13 上午10:26
     * 修改时间：
     * @version
     * @since 3.9
     */
    private static int checkLeapMonth(int offset, Integer leapMonth, Integer lunarYear, Integer lunarMonth, Integer lunarDay) throws Exception {
        for (int i = 1; i < lunarMonth; i++) {
            int tempMonthDaysCount = getMonthDays(lunarYear, i);
            offset += tempMonthDaysCount;
        }
        if (lunarMonth > leapMonth) {
            int temp = getLeapMonthDays(lunarYear); // 计算闰月天数
            offset += temp; // 加上闰月天数

            if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
                throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DATE)));
            }
            offset += lunarDay;
        } else { // 如果需要计算的是闰月，则应首先加上与闰月对应的普通月的天数
            // 计算月为闰月
            int temp = getMonthDays(lunarYear, lunarMonth); // 计算非闰月天数
            offset += temp;

            if (lunarDay > getLeapMonthDays(lunarYear)) {
                throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DATE)));
            }
            offset += lunarDay;
        }
        return offset;
    }

    /**
     * 校验农历时间格式是否符合农历规则
     *
     * @param lunarCalendar 农历时间字符串，例 1994-2-21
     *
     * @throws Exception 非法日期异常
     * @author 章华隽
     * 创建时间： 2017/7/13 下午2:25
     * 修改时间：
     * @version
     * @since 3.9
     */
    public static void checkLunarCalendar(String lunarCalendar) throws Exception {
        if (!lunarCalendar.contains("-")) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DATE)));
        }
        String[] lunars = lunarCalendar.split("-");
        if (lunars.length < 3) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DATE)));
        }
        Integer lunarYear = Integer.parseInt(lunars[0]);
        Integer lunarMonth = Integer.parseInt(lunars[1]);
        Integer lunarDay = Integer.parseInt(lunars[2]);
        checkLunarDate(lunarYear, lunarMonth, lunarDay);
        //计算该年闰几月
        int leapMonth = getLeapMonth(lunarYear);

        //当年没有闰月或月份早于闰月或和闰月同名的月份
        if (leapMonth == 0 || lunarMonth < leapMonth) {
            checkNotLeapMonth(0, lunarYear, lunarMonth, lunarDay);
        } else {//当年有闰月，且月份晚于或等于闰月
            checkLeapMonth(0, leapMonth, lunarYear, lunarMonth, lunarDay);
        }
    }

    /**
     * 判断农历或公历时间是否超过今天
     *
     * @param solarDay 公历生日时间（10位int的timestamp）
     * @param lunarDay 农历时间（字符串）例1994-02-21
     * @param isLunar 是否为农历时间
     * @return boolean 是否超过今天
     * @throws Exception 农历时间不正确，不存在这一天
     */
    public static boolean isBeyondToday(Integer solarDay, String lunarDay, boolean isLunar) throws Exception {
        if (isLunar) { // 农历校验
            if (!StringUtil.isEmpty(lunarDay)) {
                try {
                    return CalendarUtil.isLunarBeyondToday(lunarDay);
                } catch (Exception e) {
                    throw new Exception(I18nMessageUtil.getMessage(I18nStringConstant.NOT_EXIST_THIS_DAY));
                }
            }
        } else { // 公历校验
            if (solarDay != null) {
                return solarDay > DateUtil.getInt();
            }
        }
        return false;
    }

    /**
     * 校验农历时间转化为公历是否超过今天
     *
     * @param lunarCalendar 农历时间字符串，例 1994-2-21
     *
     * @return boolean
     * @throws Exception 非法日期异常
     * @author 章华隽
     * 创建时间： 2017/7/13 下午2:26
     * 修改时间：
     * @version
     * @since 3.9
     */
    public static boolean isLunarBeyondToday(String lunarCalendar) throws Exception {
        Integer temp;
        try {
            checkLunarCalendar(lunarCalendar);
            temp = lunar2Timestamp(lunarCalendar);
        } catch (Exception e) {
            throw (new Exception(I18nMessageUtil.getMessage(I18nStringConstant.ILLEGAL_LUNAR_DATE)));
        }
        return temp > DateUtil.getInt();
    }

    /**
     * 公历日期转换为农历日期
     *
     * @param solarDate 公历日期,格式YYYYMMDD
     *
     * @return 农历日期
     * @throws Exception 非法日期异常
     * @author liu 2015-1-5
     */
    public static String solarToLunar(String solarDate) throws Exception {
        int i;
        int temp = 0;
        int lunarYear;
        int lunarMonth; //农历月份
        int lunarDay; //农历当月第几天
        boolean leapMonthFlag = false;

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        Date myDate = null;
        Date startDate = null;
        try {
            myDate = formatter.parse(solarDate);
            startDate = formatter.parse(START_DATE);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        int offset = daysBetween(startDate, myDate);

        for (i = MIN_YEAR; i <= MAX_YEAR; i++) {
            temp = getYearDays(i);  //求当年农历年天数
            if (offset - temp < 1) {
                break;
            } else {
                offset -= temp;
            }
        }
        lunarYear = i;

        int leapMonth = getLeapMonth(lunarYear);//计算该年闰哪个月
        // 当年是否有闰月
        boolean isLeapYear = leapMonth > 0;

        for (i = 1; i <= 12; i++) {
            if (i == leapMonth + 1 && isLeapYear) {
                temp = getLeapMonthDays(lunarYear);
                isLeapYear = false;
                leapMonthFlag = true;
                i--;
            } else {
                temp = getMonthDays(lunarYear, i);
            }
            offset -= temp;
            if (offset <= 0) {
                break;
            }
        }

        offset += temp;
        lunarMonth = i;
        lunarDay = offset;

        return "农历：" + lunarYear + "年" + (leapMonthFlag & (lunarMonth == leapMonth) ? "闰" : "") + lunarMonth + "月" + lunarDay + "日";
    }

    /**
     * 秒级Timestamp转化为农历时间
     *
     * @param timestamp 10位整数时间
     *
     * @return 时间格式为 年-月-日 例 1994-2-21
     * @author 章华隽
     * 创建时间：2017-07-10 22:30
     * 修改时间：2017-07-12 15:45 by 章华隽
     * @version
     * @since 3.9
     */
    public static String timestamp2Lunar(Integer timestamp) throws Exception {
        if (timestamp == null) {
            return I18nMessageUtil.getMessage(I18nStringConstant.TIME_FORMAT_ERROR);
        }
        int i;
        int temp = 0;
        int lunarYear;
        int lunarMonth; //农历月份
        int lunarDay; //农历当月第几天
        Date originDate = new Date(1000L * timestamp);
        Date startDate = new SimpleDateFormat("yyyyMMdd").parse(START_DATE);

        int offset = daysBetween(startDate, originDate);

        for (i = MIN_YEAR; i <= MAX_YEAR; i++) {
            temp = getYearDays(i);  //求当年农历年天数
            if (offset - temp < 1) {
                break;
            } else {
                offset -= temp;
            }
        }
        lunarYear = i;

        int leapMonth = getLeapMonth(lunarYear);//计算该年闰哪个月
        // 当年是否有闰月
        boolean isLeapYear = leapMonth > 0;

        for (i = 1; i <= 12; i++) {
            if (i == leapMonth + 1 && isLeapYear) {
                temp = getLeapMonthDays(lunarYear);
                isLeapYear = false;
                i--;
            } else {
                temp = getMonthDays(lunarYear, i);
            }
            offset -= temp;
            if (offset <= 0) {
                break;
            }
        }

        offset += temp;
        lunarMonth = i;
        lunarDay = offset;
        return lunarYear + "-" + StringUtil.fillZero2DigitNum(lunarMonth) + "-" + StringUtil.fillZero2DigitNum(lunarDay);
    }

    /**
     * 将农历数值改为中文
     *
     * @param lunarCalendar 农历日期 例 1994-4-1
     *
     * @return 时间格式为 月日 例 二月廿一
     * @version
     * @author 章华隽
     * 创建时间：2017-07-11 10:22
     * 修改时间：2017-07-12 15:42 by 章华隽
     * @version
     * @since 3.9
     */
    public static String lunar2Str(String lunarCalendar) {
        if (!lunarCalendar.contains("-")) {
            return I18nMessageUtil.getMessage(I18nStringConstant.UNKNOW);
        }
        String[] lunars = lunarCalendar.split("-");
        if (lunars.length < 3) {
            return I18nMessageUtil.getMessage(I18nStringConstant.UNKNOW);
        }
        Integer year = Integer.parseInt(lunars[0]);
        Integer month = Integer.parseInt(lunars[1]);
        Integer day = Integer.parseInt(lunars[2]);
        String monthStr;
        String dayStr;
        switch (month) {
            case 1:
                monthStr = "正月";
                break;
            case 2:
                monthStr = "二月";
                break;
            case 3:
                monthStr = "三月";
                break;
            case 4:
                monthStr = "四月";
                break;
            case 5:
                monthStr = "五月";
                break;
            case 6:
                monthStr = "六月";
                break;
            case 7:
                monthStr = "七月";
                break;
            case 8:
                monthStr = "八月";
                break;
            case 9:
                monthStr = "九月";
                break;
            case 10:
                monthStr = "十月";
                break;
            case 11:
                monthStr = "十一月";
                break;
            case 12:
                monthStr = "腊月";
                break;
            default:
                monthStr = "XX月";
                break;
        }
        switch (day) {
            case 1:
                dayStr = "初一";
                break;
            case 2:
                dayStr = "初二";
                break;
            case 3:
                dayStr = "初三";
                break;
            case 4:
                dayStr = "初四";
                break;
            case 5:
                dayStr = "初五";
                break;
            case 6:
                dayStr = "初六";
                break;
            case 7:
                dayStr = "初七";
                break;
            case 8:
                dayStr = "初八";
                break;
            case 9:
                dayStr = "初九";
                break;
            case 10:
                dayStr = "初十";
                break;
            case 11:
                dayStr = "十一";
                break;
            case 12:
                dayStr = "十二";
                break;
            case 13:
                dayStr = "十三";
                break;
            case 14:
                dayStr = "十四";
                break;
            case 15:
                dayStr = "十五";
                break;
            case 16:
                dayStr = "十六";
                break;
            case 17:
                dayStr = "十七";
                break;
            case 18:
                dayStr = "十八";
                break;
            case 19:
                dayStr = "十九";
                break;
            case 20:
                dayStr = "二十";
                break;
            case 21:
                dayStr = "廿一";
                break;
            case 22:
                dayStr = "廿二";
                break;
            case 23:
                dayStr = "廿三";
                break;
            case 24:
                dayStr = "廿四";
                break;
            case 25:
                dayStr = "廿五";
                break;
            case 26:
                dayStr = "廿六";
                break;
            case 27:
                dayStr = "廿七";
                break;
            case 28:
                dayStr = "廿八";
                break;
            case 29:
                dayStr = "廿九";
                break;
            case 30:
                dayStr = "三十";
                break;
            default:
                dayStr = "XX日";
                break;
        }
        return StringUtil.formatChineseYear(year) + monthStr + dayStr;
    }

    /**
     * 得到农历的月和日时间筛选正则表达式
     *
     * @param timestamp 公历的10位秒级int Unix_Timestamp
     * @param days 未来的天数 > 0
     * @return 农历月和日的正则表达式
     * @throws Exception 时间格式异常
     *
     * @author 章华隽
     * 创建时间： 2017/7/21 下午10:38
     * 修改时间：
     * @version
     * @since 3.9
     */
    public static String getLunarCalendarRegexp(Integer timestamp, int days) throws Exception {
        if (timestamp == null) {
            throw new Exception(I18nMessageUtil.getMessage(I18nStringConstant.TIME_FORMAT_ERROR));
        }
        if (days < 0) {
            throw new Exception("当前只能查询今天或未来的农历生日！");
        }
        String lunarCalendar = timestamp2Lunar(timestamp);
        String[] lunars = lunarCalendar.split("-");
        List<int[]> lunarCalendarInterval = CalendarUtil.getLunarCalendarInterval(
                Integer.parseInt(lunars[0]),
                Integer.parseInt(lunars[1]),
                Integer.parseInt(lunars[2]),
                days);
        if (days == 1) { // 未来一天的需要特殊处理：不包含今天
            lunarCalendarInterval.remove(0);
        }
        StringBuilder regexp = new StringBuilder();
        for (int[] monthDay : lunarCalendarInterval) {
            regexp.append(StringUtil.fillZero2DigitNum(monthDay[0])).append("-").append(StringUtil.fillZero2DigitNum(monthDay[1])).append("$").append("|");
        }
        return regexp.substring(0, regexp.length() - 1);
    }

    /**
     * 得到未来days天的农历月和日的数组队列
     *
     * @param lunarYear 农历年
     * @param lunarMonth 农历月
     * @param lunarDay 农历天
     * @param days 未来的天数
     * @return List<int[]> 农历月和日的数组队列
     * @throws Exception 农历格式异常
     *
     * @author 章华隽
     * 创建时间： 2017/7/21 下午10:35
     * 修改时间：
     * @version
     * @since 3.9
     */
    public static List<int[]> getLunarCalendarInterval(int lunarYear, int lunarMonth, int lunarDay, int days) throws Exception {
        if (days < 0) {
            throw new Exception("当前只能查询今天或未来的农历生日！");
        }
        int leapDay = CalendarUtil.getLunarMonthDays(lunarYear, lunarMonth);// 农历该月有几天
        List<int[]> lunarCalendarInterval = new ArrayList<>();
        for (int i = 0; i < (days + 1); i++) {
            if (lunarDay > leapDay) {
                lunarDay -= leapDay;
                lunarMonth++;
                leapDay = CalendarUtil.getLunarMonthDays(lunarYear, lunarMonth);
            }
            int[] temp = new int[2];
            temp[0] = lunarMonth;
            temp[1] = lunarDay;
            lunarCalendarInterval.add(temp);
            lunarDay++;
        }
        return lunarCalendarInterval;
    }

}
